package com.jingdianjichi.oss.utils;

import com.jingdianjichi.oss.entity.FileInfo;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.apache.tika.Tika;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * minio文件操作工具
 */
@Component
public class MinioUtil {

    @Resource
    private MinioClient minioClient;

    /**
     * 创建桶
     */
    public void createBucket(String bucket) throws Exception {
        //判断桶是否存在
        boolean exists = minioClient.bucketExists(
                                     BucketExistsArgs
                                             .builder()
                                             .bucket(bucket)
                                             .build());

        //创建桶
        if (!exists){
            minioClient.makeBucket(
                    MakeBucketArgs
                            .builder()
                            .bucket(bucket)
                            .build()
            );
        }

        //如果存在就什么都不做

    }

    /**
     * 上传文件,对象名最后一个就是
     */
    public void uploadFile(InputStream inputStream,String bucket,String objectName,String name) throws Exception{
        String mime = getMIME(name);

        minioClient.putObject(
                PutObjectArgs
                        .builder()
                        .bucket(bucket)
                        .object(objectName)
                        .stream(inputStream,-1,Integer.MAX_VALUE)
                            /*
                                 -1: 这个参数表示要上传的字节数。在这里，-1 通常意味着我们不知道流的大小。MinIO 将在上传过程中读取流直到结束（即直到 InputStream 返回 -1）。
                                 Integer.MAX_VALUE: 这个参数指定了上传的最大字节数。在此情况下，Integer.MAX_VALUE 表示没有上限，允许上传的字节数最多可以达到 Integer 的最大值。
                                 如果你不用stream的话,你还要自己操作流的
                             */
                        .contentType(mime)
                        .build()
        );

    }


    /**
     * 列出所有的桶的名称
     */
    public List<String> getAllBucket() throws Exception{
        List<Bucket> buckets = minioClient.listBuckets();

        //转换成名字返回
        return buckets.stream().map(Bucket::name).collect(Collectors.toList());
    }


    /**
     *列出当前桶的文件
     */
    public List<FileInfo> getAllFile(String bucket) throws Exception{
        //结果
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs
                        .builder()
                        .bucket(bucket)
                        .build()
        );
    
        List<FileInfo> fileInfoList=new ArrayList<>();

        //转换对象返回
        for (Result<Item> result : results) {
            FileInfo fileInfo = new FileInfo();
            Item item = result.get();

            fileInfo.setFileName(item.objectName());
            fileInfo.setEtag(item.etag());
            fileInfo.setDirectoryFlag(item.isDeleteMarker());

            fileInfoList.add(fileInfo);
        }

        return fileInfoList;
    }


    /**
     * 下载文件
     */
    public InputStream downLoad(String bucket,String objectName) throws Exception{
        GetObjectResponse object = minioClient.getObject(
                GetObjectArgs
                        .builder()
                        .bucket(bucket)
                        .object(objectName)
                        .build()
        );

        return object;
    }


    /**
     *删除桶
     */
    public void deleteBucket(String bucket) throws Exception{
        minioClient.removeBucket(
                RemoveBucketArgs
                        .builder()
                        .bucket(bucket)
                        .build()
        );
    }


    /**
     * 删除文件
     */
    public void deleteObject(String bucket,String objectName) throws Exception{
        minioClient.removeObject(
                RemoveObjectArgs
                        .builder()
                        .bucket(bucket)
                        .object(objectName)
                        .build()
        );
    }
    /**
     * 获取文件url,废弃了
     */
    public String getPreviewFileUrl(String bucketName, String objectName) throws Exception{
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)     //get是默认的行为
                .bucket(bucketName)
                .object(objectName)
                .build();

        return minioClient.getPresignedObjectUrl(args);
    }

    private String getMIME(String name){
        Tika tika = new Tika();
        String mimeType = tika.detect(name);

        return mimeType;
    }


}
